#ifndef VIDEO_PROC_SUB_SYS_H_
#define VIDEO_PROC_SUB_SYS_H_

#include "DefaultDefine.h"

namespace hiych {

struct vpssChannel
{
    vpssChannel(){}
    vpssChannel(int channel,VPSS_CHN_ATTR_S attr):
        channelId(channel),
        channelAttr(attr){}

    VPSS_CHN channelId;
    VPSS_CHN_ATTR_S channelAttr;
};

struct vpssConfig
{
    VPSS_GRP grpID;
    VPSS_GRP_ATTR_S grpAttr;
    int usedChannelNum;
    vpssChannel channelConfig[VPSS_MAX_PHY_CHN_NUM];
};

//vpss类
class VideoProcSubSys
{
public:
    using DATA_VPSS_TYPE = vpssConfig;

    void setGroup(const int& grpID,VPSS_GRP_ATTR_S* attr,const SIZE_S& pictureSize);
    void setChannel(const int& channelId,VPSS_CHN_ATTR_S* attr,int width,int height);
    bool isConfigSetComplete() const;
private:
    void initVpssParam();
private:

    DATA_VPSS_TYPE* vpssParam;
    bool configFlag[2]{0};
public:

    DATA_VPSS_TYPE* getParam() const;

    VideoProcSubSys(/* args */);
    ~VideoProcSubSys();
};

VideoProcSubSys::VideoProcSubSys(/* args */):
    vpssParam(nullptr)
{
    try
    {
        vpssParam = new DATA_VPSS_TYPE;
    }
    catch(const std::bad_alloc& e)
    {
        std::cerr << e.what() << '\n';
    }
    
    memset_s(this->vpssParam, sizeof(DATA_VPSS_TYPE),0 , sizeof(DATA_VPSS_TYPE));

    initVpssParam();
}

VideoProcSubSys::~VideoProcSubSys()
{
    delete vpssParam;
}

VideoProcSubSys::DATA_VPSS_TYPE* VideoProcSubSys::getParam() const
{
    return vpssParam;
}

void VideoProcSubSys::initVpssParam()
{
    this->vpssParam->usedChannelNum = 0;
    this->vpssParam->grpID = -1;
}

void VideoProcSubSys::setGroup(const int& grpID,VPSS_GRP_ATTR_S* attr,const SIZE_S& pictureSize)
{
    HI_ASSERT(grpID >= 0);

    this->vpssParam->grpID = grpID;

    VPSS_GRP_ATTR_S* grp = &(this->vpssParam->grpAttr);

    if(attr != nullptr)
        grp = attr;
    else
    {
        grp->u32MaxH = pictureSize.u32Height;
        grp->u32MaxW = pictureSize.u32Width;
        grp->enDynamicRange = DYNAMIC_RANGE_SDR8;
        grp->enPixelFormat =PIXEL_FORMAT_YVU_SEMIPLANAR_420;
        grp->stFrameRate.s32DstFrameRate = -1;
        grp->stFrameRate.s32SrcFrameRate = -1;
        grp->bNrEn = HI_TRUE;
    }

    configFlag[0] = true;
}

void VideoProcSubSys::setChannel(const int& channelId,VPSS_CHN_ATTR_S* attr,int width,int height)
{
    vpssChannel* chn = &(this->vpssParam->channelConfig[this->vpssParam->usedChannelNum]);

    if(attr != nullptr)
        chn->channelAttr = *attr;
    else
    {
        chn->channelAttr.u32Width = width;
        chn->channelAttr.u32Height = height;

        chn->channelAttr.enChnMode = VPSS_CHN_MODE_USER;
        chn->channelAttr.enVideoFormat = VIDEO_FORMAT_LINEAR;
        chn->channelAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
        chn->channelAttr.enDynamicRange = DYNAMIC_RANGE_SDR8;
        chn->channelAttr.enCompressMode = COMPRESS_MODE_NONE;
        chn->channelAttr.stAspectRatio.enMode = ASPECT_RATIO_NONE;

        chn->channelAttr.stFrameRate.s32DstFrameRate = -1;
        chn->channelAttr.stFrameRate.s32SrcFrameRate = -1;

        chn->channelAttr.bFlip = HI_FALSE;
        chn->channelAttr.bMirror = HI_FALSE;
        chn->channelAttr.u32Depth = 2;
    }
    chn->channelId = channelId;
    
    this->vpssParam->usedChannelNum++;

    configFlag[1] = true;
}

bool VideoProcSubSys::isConfigSetComplete() const
{
    for(auto i:configFlag)
        if(configFlag[i] == false)
            return false;
            
    return true;
}

}

#endif